home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Navigation Services SDK / Examples / SimpleText / SimpleText ƒ / NavigationServicesSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-16  |  6.7 KB  |  295 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        NavigationServicesSupport.c
  3.  
  4.     Copyright:    © 1997-1998 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. #include "NavigationServicesSupport.h"
  9.  
  10.  
  11. #include <CodeFragments.h>
  12. #include <Finder.h>
  13. #include <Dialogs.h>
  14. #include <LowMem.h>
  15. #include <string.h>
  16. #include <Processes.h>
  17.  
  18. extern void ConductErrorDialog(OSErr error, short commandID, short alertType);
  19.  
  20. static Handle NewOpenHandle(OSType applicationSignature, short numTypes, OSType typeList[])
  21. {
  22.     Handle hdl = NULL;
  23.     
  24.     if ( numTypes > 0 )
  25.     {
  26.     
  27.         hdl = NewHandle(sizeof(NavTypeList) + numTypes * sizeof(OSType));
  28.     
  29.         if ( hdl != NULL )
  30.         {
  31.             NavTypeListHandle open        = (NavTypeListHandle)hdl;
  32.             
  33.             (*open)->componentSignature = applicationSignature;
  34.             (*open)->osTypeCount        = numTypes;
  35.             BlockMoveData(typeList, (*open)->osType, numTypes * sizeof(OSType));
  36.         }
  37.     }
  38.     
  39.     return hdl;
  40. }
  41.  
  42.  
  43.  
  44.  
  45. static OSStatus SendOpenAE(AEDescList list)
  46. {
  47.     OSStatus        err;
  48.     AEAddressDesc    theAddress;
  49.     AppleEvent        dummyReply;
  50.     AppleEvent        theEvent;
  51.     
  52.     theAddress.descriptorType    = typeNull;
  53.     theAddress.dataHandle        = NULL;
  54.  
  55.     do {
  56.         ProcessSerialNumber psn;
  57.     
  58.         err = GetCurrentProcess(&psn);
  59.         if ( err != noErr) break;
  60.         
  61.         err =AECreateDesc(typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber), &theAddress);
  62.         if ( err != noErr) break;
  63.             
  64.         dummyReply.descriptorType    = typeNull;
  65.         dummyReply.dataHandle        = NULL;
  66.  
  67.         err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &theAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  68.         if ( err != noErr) break;
  69.         
  70.         err = AEPutParamDesc(&theEvent, keyDirectObject, &list);
  71.         if ( err != noErr) break;
  72.         
  73.         err = AESend(&theEvent, &dummyReply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  74.         if ( err != noErr) break;
  75.         
  76.             
  77.     } while (false);
  78.     
  79.     return err;
  80. }
  81.  
  82.  
  83.  
  84. OSStatus OpenFileDialog(OSType applicationSignature, short numTypes, OSType typeList[], NavEventProcPtr eventProc, FSSpec* fileSpec, OSType* fileType)
  85. {
  86.     NavReplyRecord        theReply;
  87.     NavDialogOptions    dialogOptions;
  88.     OSErr                theErr        = noErr;
  89.     NavTypeListHandle    openList    = NULL;
  90.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  91.  
  92.     NavGetDefaultDialogOptions(&dialogOptions);
  93.     dialogOptions.dialogOptionFlags -= kNavDontAddTranslateItems;
  94.     
  95.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  96.     
  97.     openList = (NavTypeListHandle)NewOpenHandle(applicationSignature, numTypes, typeList);
  98.     if ( openList )
  99.     {
  100.         HLock((Handle)openList);
  101.     }
  102.     
  103.     theErr = NavGetFile(NULL, &theReply, &dialogOptions, eventUPP, NULL, NULL, openList, NULL);
  104.     DisposeRoutineDescriptor(eventUPP);
  105.     
  106.     if ( theErr != noErr && theErr != userCanceledErr )
  107.     {
  108.         ConductErrorDialog( theErr, 0, cancel );    
  109.         if (theErr == memFullErr)
  110.             theErr = userCanceledErr;
  111.     }
  112.     
  113.     if (theErr == noErr && theReply.validRecord)
  114.     {
  115.         // grab the target FSSpec from the AEDesc for opening:    
  116.         AEDesc     resultDesc;
  117.         FInfo    fileInfo;
  118.  
  119.         // Is this a single file open
  120.         if ( fileSpec != NULL )
  121.         {
  122.             AEKeyword keyword;
  123.             
  124.             theErr = AEGetNthDesc(&theReply.selection, 1, typeFSS, &keyword, &resultDesc);
  125.             if (theErr == noErr)
  126.                 BlockMove(*resultDesc.dataHandle,fileSpec,sizeof(FSSpec));
  127.                 
  128.             // decide if the doc we fileSpec opening is a PICT or TEXT
  129.             theErr = FSpGetFInfo(fileSpec, &fileInfo);
  130.             if (theErr == noErr)
  131.             {
  132.                 if ( fileType != NULL )
  133.                     *fileType = fileInfo.fdType;
  134.             }
  135.         }
  136.         else
  137.         {
  138.             // Multiple files open: use ApleEvents
  139.             theErr = SendOpenAE(theReply.selection);
  140.         }
  141.  
  142.         NavDisposeReply(&theReply);
  143.     }
  144.     
  145.     if (openList != NULL)
  146.     {
  147.         HUnlock((Handle)openList);
  148.         DisposeHandle((Handle)openList);
  149.     }
  150.     
  151.     return theErr;
  152. }
  153.  
  154.  
  155. short ConfirmSaveDialog(StringPtr documentName, Boolean quitting, NavEventProcPtr eventProc)
  156. {
  157.     OSStatus                theStatusErr     = noErr;
  158.     OSErr                     theErr             = noErr;
  159.     NavAskSaveChangesResult    reply             = 0;
  160.     NavAskSaveChangesAction    action             = 0;
  161.     NavEventUPP                eventUPP        = NewNavEventProc(eventProc);
  162.     NavDialogOptions        dialogOptions;
  163.     short                    result;
  164.     
  165.     if (quitting)
  166.         action = kNavSaveChangesQuittingApplication;
  167.     else
  168.         action = kNavSaveChangesClosingDocument;
  169.         
  170.     BlockMoveData(LMGetCurApName(),dialogOptions.clientName,LMGetCurApName()[0]+1);
  171.     BlockMoveData(documentName,dialogOptions.savedFileName,documentName[0]+1);
  172.     
  173.     theErr = NavAskSaveChanges(    &dialogOptions,
  174.                                 action,
  175.                                 &reply,
  176.                                 eventUPP,
  177.                                 NULL);
  178.     DisposeRoutineDescriptor(eventUPP);
  179.     
  180.     // Map reply code to ok, cancel, dontSave
  181.     switch (reply)
  182.     {
  183.         case kNavAskSaveChangesSave:
  184.             result = ok;
  185.             break;
  186.             
  187.         case kNavAskSaveChangesCancel:
  188.             result = cancel;
  189.             break;
  190.             
  191.         case kNavAskSaveChangesDontSave:
  192.             result = dontSaveChanges;
  193.             break;
  194.     }
  195.     
  196.     return result;
  197. }
  198.  
  199.  
  200.  
  201. OSStatus SaveFileDialog(StringPtr fileName, OSType filetype, OSType fileCreator, 
  202.                         NavEventProcPtr eventProc, FSSpec* fileSpec, 
  203.                         Boolean* stationery, Boolean* replacing, NavReplyRecord* reply)
  204. {
  205.     NavDialogOptions    dialogOptions;
  206.     OSErr                theErr        = noErr;
  207.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  208.  
  209.     NavGetDefaultDialogOptions(&dialogOptions);
  210.  
  211.     dialogOptions.dialogOptionFlags |= (stationery != NULL ? kNavAllowStationery : 0);
  212.     BlockMoveData(fileName, dialogOptions.savedFileName, fileName[0] + 1);
  213.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  214.  
  215.     theErr = NavPutFile(NULL, reply, &dialogOptions, eventUPP, filetype, fileCreator, NULL);
  216.     DisposeRoutineDescriptor(eventUPP);
  217.     
  218.     if (reply->validRecord)
  219.     {
  220.         // User saved
  221.         AEDesc     resultDesc;
  222.         AEKeyword keyword;
  223.             
  224.         // retrieve the returned selection:
  225.         theErr = AEGetNthDesc(&reply->selection, 1, typeFSS, &keyword, &resultDesc);
  226.         if (theErr == noErr)
  227.             BlockMove(*resultDesc.dataHandle, fileSpec, sizeof(FSSpec));
  228.  
  229.         if ( replacing != NULL )
  230.             *replacing = reply->replacing;
  231.         
  232.         if ( stationery != NULL )
  233.         {
  234.             *stationery    = reply->isStationery;
  235.         }
  236.     }
  237.     else
  238.     {
  239.         // User cancelled
  240.         if ( replacing != NULL )
  241.             *replacing = false;
  242.         
  243.         if ( stationery != NULL )
  244.             *stationery    = false;    
  245.  
  246.         theErr = userCanceledErr;
  247.     }
  248.     
  249.     return theErr;
  250. }
  251.  
  252.  
  253.  
  254. OSStatus CompleteSave(const FSSpec*, NavReplyRecord* reply)
  255. {
  256.     OSStatus theErr;
  257.     
  258.     if (reply->validRecord)
  259.     {
  260.         theErr = NavCompleteSave(reply, kNavTranslateInPlace);
  261.     }
  262.  
  263.     theErr = NavDisposeReply(reply);
  264.     
  265.     return theErr;
  266. }
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274. //
  275. // Callback to handle events that occur while navigation dialogs are up but really should be handled by the application
  276. //
  277.  
  278. extern void HandleEvent(EventRecord * pEvent);
  279.  
  280.  
  281. pascal void MyEventProc(const NavEventCallbackMessage callBackSelector, 
  282.                         NavCBRecPtr callBackParms, 
  283.                         NavCallBackUserData /*callBackUD*/)
  284. // Callback to handle event passing betwwn the navigation dialogs and the applicatio
  285. {
  286.     if ( callBackSelector == kNavCBEvent )
  287.         switch (callBackParms->eventData.event->what)
  288.         {
  289.             case updateEvt:
  290.                 HandleEvent(callBackParms->eventData.event);
  291.                 break;
  292.         }
  293. }
  294.  
  295.